﻿using System;
using Runtime.Models;
using Runtime.Services.Battle;
using Runtime.Services.Battle.Entity;
using Runtime.Services.BattleAttack;
using UnityEngine;

namespace Runtime.Services.BattleSkill {

    public abstract partial class DFR_BattleSkillServiceTD {

        private sealed class DebuffHaloBuff : DFR_BattleEffectHolder, IDFR_BattleBuffProvider {

            IDFR_BattleBuffProviderSetter IDFR_BattleBuffProvider.AsSetter() => throw new NotSupportedException();

            bool IDFR_BattleBuffProvider.IsEnablePersistence => false;

            public DFR_BattleEntityInstanceID OwnerEntityInstanceID { get; private set; }

            DFR_BattleEntityInstanceID IDFR_BattleBuffProvider.SourceEntityInstanceID => DFR_BattleEntityInstanceID.Empty;

            public DFR_BattleEntityInstanceID EntityInstanceID { get; private set; }

            private IDFR_BattleBuffProviderSetter m_BuffProvider;

            public DFR_BattleMapPosition MapPosition { get; }

            public F64 Range { get; private set; }

            public IDFR_BattleAttackSnapshot Snapshot { get; private set; }

            public DebuffHaloBuff(DFR_BattleMapPosition mapPosition, IDFR_BattleEffectModelTD effectModel, IDFR_BattleSkillModelTD skillModel) {
                OwnerEntityInstanceID = effectModel.OwnerEntityInstanceID;
                EntityInstanceID = new() { ID = effectModel.EntityInstanceID.ID };
                BattleSkillServiceTD.Instance.AddEffectModel(EntityInstanceID, effectModel);
                var buffProvider = effectModel.AsBuffProvider();
                m_BuffProvider = KHBD.TypeMap.Instantiate<IDFR_BattleBuffProviderSetter>();
                (m_BuffProvider as IDFR_BattleBuffProviderInternal).Initialize(EntityInstanceID, false, OwnerEntityInstanceID, effectModel.EntityInstanceID);
                m_BuffProvider.AttachBuff(buffProvider);
                MapPosition = mapPosition;
                var gridOption = DFR_BattleTD.DataCenter.Models.GridOption;
                Range = effectModel.RangeType switch {
                    DFR_BattleEffectRangeType.All => F64.From(Mathf.Max((int)gridOption.HorizontalCount, (int)gridOption.VerticalCount)),
                    DFR_BattleEffectRangeType.Range => F64.From(effectModel.HaloRange.Int),
                    _ => throw new NotSupportedException($"未支持的参数，如有需要请联系客户端程序 [{nameof(DFR_BattleEffectRangeType)}={effectModel.RangeType}]"),
                };

                SetModelAssetKey(effectModel.ModelAssetKey);
                if (DFR_BattleTD.DataCenter.Models.AttackSourceDictionary.TryGetValue(OwnerEntityInstanceID, out var attackSourceModel)) {
                    Snapshot = new IDFR_BattleSkillServiceTD.Snapshot(buffProvider);
                    Snapshot.Initialize(attackSourceModel.AsAttacker(), null, false, false, 0, null, false);
                }
            }

            protected override void Dispose() {
                BattleSkillServiceTD.Instance.RemoveEffectModel(EntityInstanceID);
                m_BuffProvider.Dispose();
                m_BuffProvider = null;
                EntityInstanceID = DFR_BattleEntityInstanceID.Empty;
                OwnerEntityInstanceID = DFR_BattleEntityInstanceID.Empty;
                Snapshot.Dispose();
                Snapshot = null;
                base.Dispose();
            }

            public IDFR_ReadOnlyBattleData HPBase => m_BuffProvider.HPBase;

            public IDFR_ReadOnlyBattleData HPFactor => m_BuffProvider.HPFactor;

            public IDFR_ReadOnlyBattleData HPAdditional => m_BuffProvider.HPAdditional;

            public IDFR_ReadOnlyBattleData HPMaxBase => m_BuffProvider.HPMaxBase;

            public IDFR_ReadOnlyBattleData HPMaxFactor => m_BuffProvider.HPMaxFactor;

            public IDFR_ReadOnlyBattleData HPMaxAdditional => m_BuffProvider.HPMaxAdditional;

            public IDFR_ReadOnlyBattleData DamageHPMaxBase => m_BuffProvider.DamageHPMaxBase;

            public IDFR_ReadOnlyBattleData DamageHPMaxFactor => m_BuffProvider.DamageHPMaxFactor;

            public IDFR_ReadOnlyBattleData DamageHPMaxAdditional => m_BuffProvider.DamageHPMaxAdditional;

            public IDFR_ReadOnlyBattleData DamageHPBase => m_BuffProvider.DamageHPBase;

            public IDFR_ReadOnlyBattleData DamageHPFactor => m_BuffProvider.DamageHPFactor;

            public IDFR_ReadOnlyBattleData DamageHPAdditional => m_BuffProvider.DamageHPAdditional;

            public IDFR_ReadOnlyBattleData DamageBase => m_BuffProvider.DamageBase;

            public IDFR_ReadOnlyBattleData DamageFactor => m_BuffProvider.DamageFactor;

            public IDFR_ReadOnlyBattleData DamageAdditional => m_BuffProvider.DamageAdditional;

            public IDFR_ReadOnlyBattleData AttackBase => m_BuffProvider.AttackBase;

            public IDFR_ReadOnlyBattleData AttackFactor => m_BuffProvider.AttackFactor;

            public IDFR_ReadOnlyBattleData AttackAdditional => m_BuffProvider.AttackAdditional;

            public IDFR_ReadOnlyBattleData AttackBossAdditionalBase => m_BuffProvider.AttackBossAdditionalBase;

            public IDFR_ReadOnlyBattleData AttackBossAdditionalFactor => m_BuffProvider.AttackBossAdditionalFactor;

            public IDFR_ReadOnlyBattleData AttackBossAdditionalAdditional => m_BuffProvider.AttackBossAdditionalAdditional;

            public IDFR_ReadOnlyBattleData AttackSpeedBase => m_BuffProvider.AttackSpeedBase;

            public IDFR_ReadOnlyBattleData AttackSpeedFactor => m_BuffProvider.AttackSpeedFactor;

            public IDFR_ReadOnlyBattleData AttackSpeedAdditional => m_BuffProvider.AttackSpeedAdditional;

            public IDFR_ReadOnlyBattleData CriticalBase => m_BuffProvider.CriticalBase;

            public IDFR_ReadOnlyBattleData CriticalFactor => m_BuffProvider.CriticalFactor;

            public IDFR_ReadOnlyBattleData CriticalAdditional => m_BuffProvider.CriticalAdditional;

            public IDFR_ReadOnlyBattleData CriticalPowerBase => m_BuffProvider.CriticalPowerBase;

            public IDFR_ReadOnlyBattleData CriticalPowerFactor => m_BuffProvider.CriticalPowerFactor;

            public IDFR_ReadOnlyBattleData CriticalPowerAdditional => m_BuffProvider.CriticalPowerAdditional;

            public IDFR_ReadOnlyBattleData SpottingRangeBase => m_BuffProvider.SpottingRangeBase;

            public IDFR_ReadOnlyBattleData SpottingRangeFactor => m_BuffProvider.SpottingRangeFactor;

            public IDFR_ReadOnlyBattleData SpottingRangeAdditional => m_BuffProvider.SpottingRangeAdditional;

            public IDFR_ReadOnlyBattleData MoveSpeedBase => m_BuffProvider.MoveSpeedBase;

            public IDFR_ReadOnlyBattleData MoveSpeedFactor => m_BuffProvider.MoveSpeedFactor;

            public IDFR_ReadOnlyBattleData MoveSpeedAdditional => m_BuffProvider.MoveSpeedAdditional;

            public IDFR_ReadOnlyBattleData DefenseBase => m_BuffProvider.DefenseBase;

            public IDFR_ReadOnlyBattleData DefenseFactor => m_BuffProvider.DefenseFactor;

            public IDFR_ReadOnlyBattleData DefenseAdditional => m_BuffProvider.DefenseAdditional;

            public IDFR_ReadOnlyBattleData DodgeBase => m_BuffProvider.DodgeBase;

            public IDFR_ReadOnlyBattleData DodgeFactor => m_BuffProvider.DodgeFactor;

            public IDFR_ReadOnlyBattleData DodgeAdditional => m_BuffProvider.DodgeAdditional;

            public IDFR_ReadOnlyBattleData InfluenceAmountAdditional => m_BuffProvider.InfluenceAmountAdditional;
        }
    }
}
